import 'package:analyzer/dart/element/element.dart';
import 'package:build/build.dart';
import 'package:froom_generator/processor/dao_processor.dart';
import 'package:froom_generator/processor/entity_processor.dart';
import 'package:source_gen/source_gen.dart';
import 'package:froom_generator/value_object/type_converter.dart' as froom_gen;
import 'dart:async';

import 'package:fall_data_base/fall_data_base.dart';
import '../utils/tc_util.dart';
import '../writer/fall_dao_writer.dart';
import 'package:fall_gen_base/fall_gen_base.dart';

/// 实体增强代码生成器
/// 继承GeneratorForAnnotation，为@Entity注解的类生成part文件格式的增强代码
class DaoGenerator extends GeneratorForAnnotation<Dao> {
  final String typeConverterPath;
  const DaoGenerator(this.typeConverterPath);

  @override
  FutureOr<String> generateForAnnotatedElement(
    Element element,
    ConstantReader annotation,
    BuildStep buildStep,
  ) async {
    LogUtil.d('🔥 DaoGenerator: 开始处理 ${element.name}');

    // 确保element是ClassElement
    if (element is! ClassElement) {
      throw InvalidGenerationSourceError(
        'DaoGenerator只能应用于类，但发现应用于${element.runtimeType}',
        element: element,
      );
    }

    try {
      LogUtil.d('🔥 DaoGenerator: 开始加载TypeConverters for ${element.name}');

      // 动态加载TypeConverter
      final typeConverters = await _loadTypeConverters(buildStep);
      LogUtil.d(
          '🔥 DaoGenerator: 加载了 ${typeConverters.length} 个TypeConverters');

      // 读取是否有DB的Annotation
      String dbName = TcUtil.getDbName(element);

      // 获取DAO的泛型实体类型
      ClassElement? entityElement;

      // 从BaseDao<T>的泛型参数中获取实体类型
      final supertype = element.supertype;
      if (supertype != null && supertype.element.name == 'BaseDao') {
        final typeArguments = supertype.typeArguments;
        if (typeArguments.isNotEmpty) {
          final entityType = typeArguments.first;
          entityElement = entityType.element as ClassElement?;
        }
      }

      if (entityElement == null) {
        throw InvalidGenerationSourceError(
          '无法从 ${element.name} 中获取实体类型，请确保继承自 BaseDao<T>',
          element: element,
        );
      }

      LogUtil.d('🔥 DaoGenerator: 找到实体类型 ${entityElement.name}');

      // 处理实体类
      final entityProcessor = EntityProcessor(entityElement, typeConverters);
      final entity = entityProcessor.process();
      LogUtil.d('🔥 DaoGenerator: 实体处理完成，开始处理DAO');

      // 使用DaoProcessor解析DAO
      final processor = DaoProcessor(
        element,
        element.displayName,
        dbName,
        [entity], // entities
        [], // views
        typeConverters,
      );
      final dao = processor.process();
      LogUtil.d('🔥 DaoGenerator: DAO处理完成，开始生成代码');

      // 使用FallDaoWriter生成DAO实现代码
      final daoWriter = FallDaoWriter(dao, entity, buildStep);
      return daoWriter.write();
    } catch (e) {
      LogUtil.d('🔥 DaoGenerator: 生成失败 for ${element.name}: $e');
      throw InvalidGenerationSourceError(
        '为类${element.name}生成增强代码时出错: $e',
        element: element,
      );
    }
  }

  /// 动态加载TypeConverter类
  Future<Set<froom_gen.TypeConverter>> _loadTypeConverters(
      BuildStep buildStep) async {
    try {
      // 使用ClassUtil加载TypeConverter子类
      final typeConverterClasses = await TcUtil.loadTypeConverters(
        buildStep,
        typeConverterPath,
      );

      // 使用TcUtil转换为froom_gen.TypeConverter
      if (typeConverterClasses.isNotEmpty) {
        LogUtil.d(
            '🗦️ _loadTypeConverters: 尝试转换${typeConverterClasses.length}个ClassElement为TypeConverter...');

        try {
          final convertedTypeConverters = TcUtil.getTypeConverters(
            typeConverterClasses,
            froom_gen.TypeConverterScope.database, // 默认作用域
          );
          LogUtil.d(
              '✅ _loadTypeConverters: 成功加载 ${convertedTypeConverters.length} 个TypeConverter');
          LogUtil.d('成功加载 ${convertedTypeConverters.length} 个TypeConverter');
          return convertedTypeConverters;
        } catch (e) {
          LogUtil.d('⚠️ _loadTypeConverters: 转换TypeConverter时发生错误: $e');
          return <froom_gen.TypeConverter>{};
        }
      }

      LogUtil.d('⚠️ _loadTypeConverters: 未在文件中找到任何TypeConverter类');
      return <froom_gen.TypeConverter>{};
    } catch (e) {
      LogUtil.d('⚠️ _loadTypeConverters: 加载TypeConverter时发生错误: $e');
      return <froom_gen.TypeConverter>{};
    }
  }
}
